package controllers

import (
	"lao-a/helper"
	"lao-a/models"
	"reflect"

	"github.com/astaxie/beego"
	"github.com/astaxie/beego/config"
	"github.com/yl10/kit/orm"

	"net/http"
)

//Message api统一的返回消息格式
type Message struct {
	Code    int         `json:"code"`
	Message interface{} `json:"message"`
}

//BaseController 基础controller
type BaseController struct {
	beego.Controller
	Context *helper.Context
	AliConf map[string]string
}

const (
	SESSION_USER = "h5.user"
	PAGENUM      = 10
)

// BaseControllerInterface 项目约定的 Controller 须满足的接口
type BaseControllerInterface interface {
	Constructor()
}

//Prepare 继承beego的
func (c *BaseController) Prepare() {
	// 读阿里云配置
	c.aliConfInit()

	// 初始化上下文
	c.initContext()
	c.Context.Ready(nil)

	// 校验路由权限
	c.auth()

	// 路由对应的实际 Controller 初始化
	c.initController()
}

// ResponseJson 自定义的JSON返回
func (c *BaseController) ResponseJson(msg interface{}, code ...int) {
	status := http.StatusOK
	if len(code) > 0 {
		status = code[0]
	}

	if status < http.StatusMultipleChoices {
		c.Context.Commit()
	} else {
		c.Context.RollBack()
	}

	c.Context.Destroy()

	if reflect.ValueOf(msg).Type().String() == "*errors.errorString" {
		err := msg.(error)
		c.Data["json"] = Message{status, err.Error()}
	} else {
		c.Data["json"] = Message{status, msg}
	}

	c.ServeJSON()
	c.StopRun()
}

// initContext 初始化 Context
func (c *BaseController) initContext() {
	// 分页设置
	pageSetting := map[string]int{
		"pageNum": 100,
	}
	// 初始化 orm
	o, _ := orm.NewXormPlus(models.Dao.NewSession())
	o.SetPageNavi(pageSetting)

	c.Context = helper.NewContext(o, nil)
}

// initAppController 执行当前路由请求对应的 Controller 初始化
func (c *BaseController) initController() {
	if ctrl, ok := c.AppController.(BaseControllerInterface); ok {
		ctrl.Constructor()
	}
}

// UploadFileToAliOSS 上传文件到阿里云
func (c *BaseController) UploadFileToAliOSS(inputField string) (string, error) {
	endpoint := c.AliConf["oss::Endpoint"]
	accessKeyID := c.AliConf["oss::AccessKeyId"]
	accessKeySecret := c.AliConf["oss::AccessKeySecret"]
	bucket := c.AliConf["oss::Bucket"]

	aliCli, err := helper.GetOssClient(endpoint, accessKeyID, accessKeySecret)
	if err != nil {
		return "", helper.LogError("配置阿里云客户端失败", err)
	}

	fileURL, err := helper.UploadFileToBucket(aliCli, c.Ctx.Request, bucket, inputField)
	if err != nil {
		return "", helper.LogError("上传文件到阿里云失败", err)
	}

	return fileURL, nil
}

// UploadStringToAliOSS 上传文件到阿里云
func (c *BaseController) UploadStringToAliOSS(fStr string) (string, error) {
	endpoint := c.AliConf["oss::Endpoint"]
	accessKeyID := c.AliConf["oss::AccessKeyId"]
	accessKeySecret := c.AliConf["oss::AccessKeySecret"]
	bucket := c.AliConf["oss::Bucket"]

	aliCli, err := helper.GetOssClient(endpoint, accessKeyID, accessKeySecret)
	if err != nil {
		return "", helper.LogError("配置阿里云客户端失败", err)
	}

	fileURL, err := helper.UploadStringToBucket(aliCli, bucket, fStr)
	if err != nil {
		return "", helper.LogError("上传文件到阿里云失败", err)
	}

	return fileURL, nil
}

func (c *BaseController) aliConfInit() {
	aliConf, err := config.NewConfig("ini", "conf/aliyun.conf")
	if err != nil {
		c.ResponseJson(
			helper.LogError("读取阿里云配置文件失败", err),
			http.StatusInternalServerError,
		)
	}

	c.AliConf = map[string]string{
		"oss::Endpoint":        aliConf.String("oss::Endpoint"),
		"oss::AccessKeyId":     aliConf.String("oss::AccessKeyId"),
		"oss::AccessKeySecret": aliConf.String("oss::AccessKeySecret"),
		"oss::Bucket":          aliConf.String("oss::Bucket"),
		"oss::ImageSuffix":     aliConf.String("oss::ImageSuffix"),
	}
}
